import logging

from crontab import CronTab
from django.contrib.auth.models import User
from django.core.exceptions import ObjectDoesNotExist
from django.db import transaction

from django.core.paginator import Paginator, PageNotAnInteger, EmptyPage
from rest_framework.authentication import TokenAuthentication
from rest_framework.parsers import JSONParser
from rest_framework.views import APIView

from backend.common.api_response import JsonResponse
from backend.common.common import record_dynamic
from backend.models import Sys_Environment, Project, Sys_Project, Sys_Model, Lyzd_Interface, Lyzd_Interface_Case, \
    Sys_Dic, \
    Lyzd_Interface_Header, Lyzd_Interface_Param, Lyzd_Interface_Case_Param, \
    Lyzd_Interface_Case_Check
from backend.serializers import Sys_ProjectSerializer, SysDicSerializer, \
    Sys_ModelSerializer, Sys_InterfaceSerializer, Sys_CaseSerializer, Lyzd_Interface_HeaderSerializer, \
    Lyzd_InterfaceParamSerializer
from backend.serializers import SysEnvironmentSerializer
from backend.models import *

logger = logging.getLogger(__name__)  # 这里使用 __name__ 动态搜索定义的 logger 配置，这里有一个层次关系的知识点。
"""
通用--DB

"""


class runMessage:
    def addMsg(msg, model):
        msg_data = Lyzd_RunMsg(
            msg=msg,  # 接口中文名
            model=model  # 接口英文名 方法名

        )

        msg_data.save()

    #     删除最新记录
    def delMsg(self):
        Lyzd_RunMsg.objects.last().delete()


# interface通用操作数据库方法
class Interface:
    """增加接口全参"""

    def addInterface(interface_name_zh, interface_name_en, requestType, encryption, decrypt, authentication
                     , create_user, inParamShow, outParamShow, content, project_id, model_id,ApiHttpType,isList,listPadding):
        api_data = Lyzd_Interface(
            interface_name_zh=interface_name_zh,  # 接口中文名
            interface_name_en=interface_name_en,  # 接口英文名 方法名
            request_type=requestType,  # 请求方式
            encryption=encryption,  # 加密url
            decrypt=decrypt,  # 解密URL
            authentication=authentication,  # 是否加密
            delete_flag='0',  # 默认0
            create_user=create_user,  # 当前登陆账号
            in_param_show=inParamShow,  # 入参示例
            out_param_show=outParamShow,  # 出参示例
            content=content,  # 备注内容
            project_id=project_id,  # 关联项目表外键
            model_id=model_id , # 关联模块表外键
            ApiHttpType=ApiHttpType,
            isList=isList,
            listPadding=listPadding
        )

        api_data.save()

    """增加接口参数表接口"""

    def addInterfaceParam(param_key, param_type, interface_id, relation, relation_interface_id, relation_interface_key,random_number,random_number_type):
        interfaceParam = Lyzd_Interface_Param(
            param_key=param_key,  # 入参,
            param_type=param_type,  # 入参类型
            interface_id=interface_id,  # 主表id
            relation=relation,  # 是否关联
            relation_interface_id=relation_interface_id,  # 关联接口id
            relation_interface_key=relation_interface_key,
            random_number=random_number,
            random_number_type=random_number_type

        )
        interfaceParam.save()

    """增加接口参数表接口"""

    def addInterfaceHeader(header_key, header_key_value, param_type, interface_id, relation, relation_interface_id,
                           relation_interface_key):
        interfaceHeader = Lyzd_Interface_Header(
            header_key=header_key,  # 入参,
            header_key_value=header_key_value,
            param_type=param_type,  # 入参类型
            interface_id=interface_id,  # 主表id
            relation=relation,  # 是否关联
            relation_interface_id=relation_interface_id,  # 关联接口id
            relation_interface_key=relation_interface_key
        )
        interfaceHeader.save()

    def addCase(case_name, create_user, modify_user, check_type, case_type,
                interface_id, action_condition, project_id):
        if action_condition == None or action_condition == '':
            action_condition = ''

        case_data = Lyzd_Interface_Case(
            case_name=case_name,  # 用例名称
            # check_sql=check_sql,  # ----校验sql迁移到从表
            project_id=project_id,  # 预期值--迁移到从表
            action_condition=action_condition,  # 校验关键字
            create_user=create_user,
            modify_user=modify_user,
            check_type=check_type,  # 校验分类
            case_type=case_type,  # 用例分类
            delete_flag=0,  # 状态默认0启用
            interface_id=interface_id  # 关联接口id

        )
        case_data.save()

    def addCaseParam(interface_id, create_user, modify_user, param_key, param_value, interface_cases_id):
        case_param = Lyzd_Interface_Case_Param(
            interface_id=interface_id,  # 用例名称
            create_user=create_user,  # ----校验sql迁移到从表
            modify_user=modify_user,  # 预期值--迁移到从表
            param_key=param_key,  # 校验关键字
            param_value=param_value,
            interface_cases_id=interface_cases_id

        )
        case_param.save()

    # def addCaseHeaderParam(interface_id, create_user, modify_user, header_key, header_value, interface_cases_id):
    #     case_header_param = Lyzd_Interface_Header_Param(
    #         interface_id=interface_id,  # 用例名称
    #         create_user=create_user,  # ----校验sql迁移到从表
    #         modify_user=create_user,  # 预期值--迁移到从表
    #         header_key=header_key,  # 校验关键字
    #         header_value=header_value,
    #
    #         interface_cases_id=str(interface_cases_id)
    #
    #     )
    #     case_header_param.save()
    #
    #     """
    #     response情况下增加casecheck
    #     """

    def addCaseCheck(expect_value, create_user, modify_user, check_key, check_condition, interface_cases_id
                     ):
        case_check = Lyzd_Interface_Case_Check(
            expect_value=expect_value,  # 用例名称
            create_user=create_user,  # ----校验sql迁移到从表
            modify_user=modify_user,  # 预期值--迁移到从表
            check_key=check_key,  # 校验关键字
            check_condition=check_condition,
            interface_cases_id=str(interface_cases_id)

        )
        case_check.save()

    """
    response情况下增加casecheck
    """

    def addCaseCheckDB(sqlExpect, sql, create_user, modify_user, interface_cases_id):
        case_check = Lyzd_Interface_Case_Check(
            expect_value=sqlExpect,  # DB情况下的预期值
            create_user=create_user,  # ----校验sql迁移到从表
            modify_user=modify_user,  # 预期值--迁移到从表
            check_sql=sql,  # 校验sql
            interface_cases_id=str(interface_cases_id)

        )
        case_check.save()


# 查询语句

class Project():
    def getProjectName(progect_id):
        project_name = list(Sys_Project.objects.filter(id=progect_id).values('project_name'))[0]['project_name']
        return project_name


class Environment():
    def getEnvironmentAddress(environment_id):
        environment_address = list(Sys_Environment.objects.filter(id=environment_id).values('address'))
        return environment_address

    def getEnvironmentName(environment_id):
        environment_name = list(Sys_Environment.objects.filter(id=environment_id).values('env_name'))
        return environment_name


class Interfaces():
    def getInterfacesAuthentication(interfaces_id):
        interfaces_authentication = list(Lyzd_Interface.objects.filter(id=interfaces_id).values('authentication'))[0][
            'authentication']
        return interfaces_authentication

    def getInterfacesEncryption(interfaces_id):
        interfaces_encryption_url = list(Lyzd_Interface.objects.filter(id=interfaces_id).values('encryption'))[0][
            'encryption']
        return interfaces_encryption_url

    def getInterfacesDecrypt(interfaces_id):
        interfaces_decrypt_url = list(Lyzd_Interface.objects.filter(id=interfaces_id).values('decrypt'))[0]['decrypt']
        return interfaces_decrypt_url

    def getInterfacesApi(interfaces_id):
        interfaces_api = [a for a in Lyzd_Interface.objects.filter(id=interfaces_id).values('interface_name_en')][0][
            'interface_name_en']
        return interfaces_api

    def getInterfacesMethod(interfaces_id):
        interfaces_method = list(Lyzd_Interface.objects.filter(id=interfaces_id).values('request_type'))[0][
            'request_type']
        return interfaces_method

    def getInterfacesName(interfaces_id):
        interfaces_name = list(Lyzd_Interface.objects.filter(id=interfaces_id).values('interface_name_zh'))[0][
            'interface_name_zh']
        return interfaces_name

    def getApiHttpType(interfaces_id):
        interfaces_apihttpyype = list(Lyzd_Interface.objects.filter(id=interfaces_id).values('ApiHttpType'))[0]['ApiHttpType']

        return interfaces_apihttpyype

    def getIsList(interfaces_id):
        testcases_isList = list(Lyzd_Interface.objects.filter(id=interfaces_id).values('isList'))[0]['isList']
        return testcases_isList

    def getListPadding(interfaces_id):
        testcases_listPadding = list(Lyzd_Interface.objects.filter(id=interfaces_id).values('listPadding'))[0]['listPadding']
        return testcases_listPadding


class Interfaces_Param():
    def getInterfacesParams(interfaces_id):
        interfaces_param_key = list(
            Lyzd_Interface_Param.objects.filter(interface=interfaces_id).values('param_key', 'param_type',
                                                                                'random_number', 'random_number_type'))
        return interfaces_param_key


class Interface_Case_Param():
    def getTestcasesParamValues(testcase_id, param_key):
        testcases_param_values = list(
            Lyzd_Interface_Case_Param.objects.filter(interface_cases=testcase_id, param_key=param_key).values(
                'param_value'))
        return testcases_param_values


class Interfaces_Header():
    def getInterfacesHeader(interfaces_id):
        testcases_header_key = list(
            Lyzd_Interface_Header.objects.filter(interface=interfaces_id).values('header_key', "header_key_value"))
        return testcases_header_key


class Interfaces_Case():
    def getInterfacesCases(interfaces_id, execute):
        testcases = list(
            Lyzd_Interface_Case.objects.filter(interface=interfaces_id, case_type=execute, delete_flag=0).values('id'))
        return testcases
    """execute 1101   也就是流程测试，不需要execute，直接查询"""
    def getInterfacesCasesFlow(interfaces_id):
        testcases = list(
            Lyzd_Interface_Case.objects.filter(interface=interfaces_id, delete_flag=0).values('id'))
        return testcases

    def getCaseName(testcase_id):
        testcases_case_name = list(Lyzd_Interface_Case.objects.filter(id=testcase_id).values('case_name'))[0][
            'case_name']
        return testcases_case_name

    def getCaseType(testcase_id):
        testcases_case_type = list(Lyzd_Interface_Case.objects.filter(id=testcase_id).values('case_type'))[0][
            'case_type']
        return testcases_case_type

    def getCheckType(testcase_id):
        testcases_check_type = list(Lyzd_Interface_Case.objects.filter(id=testcase_id).values('check_type'))[0][
            'check_type']
        return testcases_check_type

    def getActionCondition(testcase_id):
        testcases_action_condition = \
            list(Lyzd_Interface_Case.objects.filter(id=testcase_id).values('action_condition'))[0]['action_condition']
        return testcases_action_condition


class Interfaces_Case_Check():
    def getCaseCheckID(testcase_id):
        check_ids = list(Lyzd_Interface_Case_Check.objects.filter(interface_cases=testcase_id).values('id'))
        return check_ids

    def getTestcasesCheckKey(testcase_id):
        testcases_check_key = list(Lyzd_Interface_Case_Check.objects.filter(id=testcase_id).values('check_key'))[0][
            'check_key']
        return testcases_check_key

    def getTestcasesCheckCondition(testcase_id):
        testcases_check_condition = \
            list(Lyzd_Interface_Case_Check.objects.filter(id=testcase_id).values('check_condition'))[0][
                'check_condition']
        return testcases_check_condition

    def getTestcasesExpectValue(testcase_id):
        testcases_expect_value = \
            list(Lyzd_Interface_Case_Check.objects.filter(id=testcase_id).values('expect_value'))[0]['expect_value']
        return testcases_expect_value


class Interface_Action():
    def addInterfaceAction(progectId, environmentId, interface_pici, interface_action, interface_action_name_list,
                           interface_action_count,
                           interface_succcess_list, interface_succcess_name_list, interface_succcess_count,
                           interface_fail_list, interface_fail_name_list, interface_fail_count, interface_res, execute):
        Lyzd_Interface_Action.objects.create(project=progectId,
                                             environment=environmentId,
                                             interface_pici=interface_pici,
                                             interface_action=interface_action,
                                             interface_action_name=interface_action_name_list,
                                             interface_action_count=interface_action_count,
                                             interface_aciton_succcess=interface_succcess_list,
                                             interface_aciton_succcess_name=interface_succcess_name_list,
                                             interface_aciton_succcess_count=interface_succcess_count,
                                             interface_aciton_fail_name=interface_fail_name_list,
                                             interface_aciton_fail=interface_fail_list,
                                             interface_aciton_fail_count=interface_fail_count,
                                             interface_res=interface_res,
                                             case_type=execute
                                             )

    #     查询成功个数及失败个数
    def getCountList(interface_pici):
        count_list = list(Lyzd_Interface_Action.objects.filter(interface_pici=interface_pici).values(
            "interface_aciton_succcess_count", "interface_aciton_fail_count"))
        return count_list

    # 更新数据
    def updateInterfaceAction(interface_pici, success_lists, success_count, interface_aciton_succcess_name, fail_lists,
                              file_count, interface_aciton_fail_name):
        Lyzd_Interface_Action.objects.filter(interface_pici=interface_pici).update(
            interface_aciton_succcess=success_lists,
            interface_aciton_succcess_count=success_count,
            interface_aciton_succcess_name=interface_aciton_succcess_name,
            interface_aciton_fail=fail_lists, interface_aciton_fail_count=file_count,
            interface_aciton_fail_name=interface_aciton_fail_name)

    #   更新执行状态
    def updateInterfaceRes(interface_pici, interface_res):
        Lyzd_Interface_Action.objects.filter(interface_pici=interface_pici).update(interface_res=interface_res)


class InterfaceCase_Action():
    # 插入数据
    def addInterfaceCaseAction(interface_pici, interfaces_id, testcase_id, interface_name, interface_case_name,
                               check_key_lists, check_condition_lists,
                               check_value_lists, out_value_lists, interface_res):
        Lyzd_InterfaceCase_Action.objects.create(interface_pici=interface_pici, interface=interfaces_id,
                                                 interface_case=testcase_id, interface_name=interface_name,
                                                 interface_case_name=interface_case_name,
                                                 check_key=check_key_lists, check_condition=check_condition_lists,
                                                 check_value=check_value_lists, out_value=out_value_lists,
                                                 interface_res=interface_res)

    #     无测试案例时，创造的伪数据
    def addInterfaceCaseAction2(interface_pici, interfaces_id, interface_name, interface_case_name,
                                check_key_lists, check_condition_lists,
                                check_value_lists, out_value_lists, interface_res):
        Lyzd_InterfaceCase_Action.objects.create(interface_pici=interface_pici, interface=interfaces_id,
                                                 interface_name=interface_name,
                                                 interface_case_name=interface_case_name,
                                                 check_key=check_key_lists, check_condition=check_condition_lists,
                                                 check_value=check_value_lists, out_value=out_value_lists,
                                                 interface_res=interface_res)

    # 查询数据（具体一个id）
    def getInterfaceCaseActionID(interface_pici, interface_name, interface_case_name):
        Lyzd_InterfaceCase_Action_id = Lyzd_InterfaceCase_Action.objects.filter(interface_pici=interface_pici,
                                                                                interface_name=interface_name,
                                                                                interface_case_name=interface_case_name).values(
            "id")
        return Lyzd_InterfaceCase_Action_id

    # 查询数据（本批次下所有的id）
    def getInterfaceCaseActionIDs(interface_pici):
        Lyzd_InterfaceCase_Action_ids = list(
            Lyzd_InterfaceCase_Action.objects.filter(interface_pici=interface_pici).values("id"))
        return Lyzd_InterfaceCase_Action_ids

    #     删除本批次下的所有用例数据
    def delInterfaceCaseAction(interface_pici, success_interface):
        Lyzd_InterfaceCase_Action.objects.filter(interface_pici=interface_pici, interface_id=success_interface).delete()


class Interface_Action_Detail():

    # 新增数据
    def addInterfaceActionDetail(interfacecase_action_id, interface_case_name, check_key, check_condition, check_value,
                                 out_value, action_condition, param_in, param_out, interface_res):
        Lyzd_Interface_Action_Detail.objects.create(interfacecase_action=interfacecase_action_id,
                                                    interface_case_name=interface_case_name,
                                                    check_key=check_key, check_condition=check_condition,
                                                    check_value=check_value, out_value=out_value,
                                                    action_condition=action_condition,
                                                    param_in=param_in, param_out=param_out,
                                                    interface_res=interface_res, )

    # 删除数据
    def delInterfaceActionDetail(interfacecase_action):
        Lyzd_Interface_Action_Detail.objects.filter(interfacecase_action=interfacecase_action).delete()


# FooModel.objects.filter(whatever="anything").update(**my_data_dict)
# User.objects.filter(id=1).update(username='nick',is_active=True)
"""
按条件更新表字段


id = models.AutoField(primary_key=True)
    interface = models.ForeignKey(Lyzd_Interface, on_delete=models.CASCADE, verbose_name="接口外键")
    param_key = models.CharField(max_length=50, verbose_name="入参key")
    param_type = models.CharField(max_length=50, verbose_name="入参类型", choices=PARAM_TYPE)
    random_number = models.CharField(max_length=50, verbose_name="随机数", choices=Random_Number)
    random_number_type = models.CharField(max_length=50, verbose_name="随机数_类型", choices=Random_Number_Type)
    relation = models.CharField(max_length=5, default="0", verbose_name="依赖接口", choices=relation)
    relation_interface_id = models.CharField(max_length=50, verbose_name="依赖关系接口id")
    relation_interface_key = models.CharField(max_length=50, verbose_name="依赖关系接口key")

    create_time = models.DateTimeField(auto_now=True, verbose_name='创建时间')
    last_update_time = models.DateTimeField(auto_now=True, verbose_name='最近修改时间')


"""


class UpdataInterface():
    def UpdateInterfaceParam(param_key, interface_id, param_type, relation, relation_interface_id,
                             relation_interface_key):
        Lyzd_Interface_Param.objects.filter(param_key=param_key, interface_id=interface_id).update(
            param_type=param_type,  # 入参类型
            interface_id=interface_id,  # 主表id
            relation=relation,  # 是否关联
            relation_interface_id=relation_interface_id,  # 关联接口id
            relation_interface_key=relation_interface_key
        )

    def UpdateInterfaceHeader(header_key, param_type, interface_id, relation, relation_interface_id,
                              relation_interface_key):
        Lyzd_Interface_Header.objects.filter(header_key=header_key, interface_id=interface_id).update(
            param_type=param_type,  # 入参类型
            relation=relation,  # 是否关联
            relation_interface_id=relation_interface_id,  # 关联接口id
            relation_interface_key=relation_interface_key
        )

    # updateInterfaceHeader2
    def UpdateInterfaceHeader2(header_key, header_key_value, param_type, interface_id, relation, relation_interface_id,
                               relation_interface_key):
        interfaceHeader = Lyzd_Interface_Header(
            header_key=header_key,  # 入参,
            header_key_value=header_key_value,
            param_type=param_type,  # 入参类型
            interface_id=interface_id,  # 主表id
            relation=relation,  # 是否关联
            relation_interface_id=relation_interface_id,  # 关联接口id
            relation_interface_key=relation_interface_key
        )
        interfaceHeader.save()

        Lyzd_Interface_Header.objects.filter(header_key=header_key, interface_id=interface_id).update(
            param_type=param_type,  # 入参类型
            relation=relation,  # 是否关联
            relation_interface_id=relation_interface_id,  # 关联接口id
            relation_interface_key=relation_interface_key
        )

    def UpdateInterface(interface_name_zh, project_id, interface_name_en, request_type, authentication, encryption,
                        decrypt, in_param_show, out_param_show, content,
                        model):
        Lyzd_Interface.objects.filter(interface_name_zh=interface_name_zh, project_id=project_id, ).update(
            interface_name_en=interface_name_en,
            request_type=request_type,
            authentication=authentication,
            encryption=encryption,
            decrypt=decrypt,

            in_param_show=in_param_show,
            out_param_show=out_param_show,

            content=content,
            model=model
        )
    """修改接口 默认不选请求方式 ，2保留冯凯可能excel导入用的到 """
    def UpdateInterface3(interface_name_zh, interface_id, interface_name_en,
                         # request_type,
                         authentication, encryption,
                         decrypt, in_param_show, out_param_show, content,
                         model,ApiHttpType,isList,listPadding):
        Lyzd_Interface.objects.filter(id=interface_id).update(
            interface_name_zh=interface_name_zh,
            interface_name_en=interface_name_en,
            # request_type=request_type,
            authentication=authentication,
            encryption=encryption,
            decrypt=decrypt,
            in_param_show=in_param_show,
            out_param_show=out_param_show,
            ApiHttpType=ApiHttpType,
            content=content,
            model=model,
            isList=isList,
            listPadding=listPadding
        )
    """导入的时候带request——type """
    def UpdateInterface2(interface_name_zh, interface_id, interface_name_en,
                         request_type,
                         authentication, encryption,
                         decrypt, in_param_show, out_param_show, content,
                         model):
        Lyzd_Interface.objects.filter(id=interface_id).update(
            interface_name_zh=interface_name_zh,
            interface_name_en=interface_name_en,
            request_type=request_type,
            authentication=authentication,
            encryption=encryption,
            decrypt=decrypt,
            in_param_show=in_param_show,
            out_param_show=out_param_show,

            content=content,
            model=model
        )


"""更新用例相关

lyzd_interface_case  interface_id  case_name
lyzd_interface_case_check   和case_id
lyzd_interface_header_param interface_id 和case_id

"""


class UpdataCase():  # interface_cases_key???
    def UpdateCaseParam(interface_id, modify_user, param_key, param_value, interface_cases_id):
        Lyzd_Interface_Case_Param.objects.filter(interface_cases__id=interface_cases_id,
                                                 interface_id=interface_id).update(
            param_key=param_key,  # 入参Key
            param_value=param_value,  # 入参值
            interface_id=interface_id,  # 主表id
            modify_user=modify_user,  # 是否关联
            interface_cases_id=interface_cases_id  # 用例id
        )

    """更新case主表"""

    def updateCase(case_name, create_user, modify_user, check_type, case_type,
                   interface_id, action_condition):
        Lyzd_Interface_Case.objects.filter(interface_id=interface_id, case_name=case_name).update(

            action_condition=action_condition,  # 校验关键字
            create_user=create_user,
            modify_user=modify_user,
            check_type=check_type,  # 校验分类
            case_type=case_type,  # 用例分类
            delete_flag=0  # 状态默认0启用
        )

    """
    更新CaseCheck
    interface_id 和case_id"""

    def updateCaseCheck(expect_value, create_user, modify_user, check_key, check_condition, interface_cases_id
                        ):
        Lyzd_Interface_Case_Check.objects.filter(interface_cases_id=interface_cases_id).update(
            expect_value=expect_value,  # 用例名称
            create_user=create_user,  # ----校验sql迁移到从表
            modify_user=modify_user,  # 预期值--迁移到从表
            check_key=check_key,  # 校验关键字
            check_condition=check_condition
        )

    """
    更新caseheaderparam
    interface_id 和case_id
    """

    # def updateHeaderParam(interface_id, create_user, header_key, header_value, interface_cases_id):
    #     Lyzd_Interface_Header_Param.objects.filter(interface_id=interface_id,
    #                                                interface_cases_id=interface_cases_id).update(
    #         create_user=create_user,  # ----校验sql迁移到从表
    #         modify_user=create_user,  # 预期值--迁移到从表
    #         header_key=header_key,  # 校验关键字
    #         header_value=header_value
    #     )
